package utilStr

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"
	"time"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

func SubString(source string, start int, length int) string {
	var r = []rune(source)
	realLength := len(r)
	var end int = realLength
	if start < 0 {
		start = realLength + start
	}

	if length > 0 {
		end = start + length
	}

	if end > realLength {
		end = realLength
	}
	if start < 0 || start >= realLength {
		return ""
	}

	if start == 0 && end == realLength {
		return source
	}

	if start == end {
		return string(r[start])
	}

	var substring = ""
	for i := start; i < realLength; i++ {

		if i >= end {
			break
		}
		substring += string(r[i])
	}

	return substring
}
func RandString(n int, chars ...string) string {
	//letterBytes := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
	letterBytes := "abcdefhkmnprstuvwxyzABCEFGHIJKLMNPRSTUVWXYZ1234567890"
	if len(chars) >= 1 {
		letterBytes = strings.Join(chars, "")
	}
	b := make([]byte, n)
	letterBytesLen := len(letterBytes)
	//r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := range b {
		if 0 == i && len(chars) <= 0 {
			b[i] = letterBytes[rand.Intn(letterBytesLen-10)] //首位为字母
		} else {
			b[i] = letterBytes[rand.Intn(letterBytesLen)]
		}

	}
	return string(b)
}

func RandPassword(n int, no_special ...bool) string {
	//letterBytes := "abcdefhkmnprstuvwxyzABCEFGHIJKLMNPRSTUVWXYZ1234567890"
	letterUp := "ABCEFGHIJKLMNPRSTUVWXYZ"
	letterLower := "abcdefhkmnprstuvwxyz"
	letterDigits := "1234567890"
	letterSpecial := "!@#$%&*?"
	noSpecial := false
	if len(no_special) >= 1 {
		noSpecial = no_special[0]
	}

	password := RandString(1, letterUp) + RandString(1, letterLower) + RandString(1, letterDigits)
	lastN := n - 3
	if !noSpecial {
		password += RandString(1, letterSpecial)
		lastN -= 1
	}
	if lastN > 0 {
		password += RandString(lastN, letterUp, letterLower, letterDigits)
	}
	passwordBytes := []byte(password)
	for i := len(passwordBytes) - 1; i > 0; i-- {
		num := rand.Intn(i + 1)
		passwordBytes[i], passwordBytes[num] = passwordBytes[num], passwordBytes[i]
	}

	return string(passwordBytes)
}

func StrIsStartWith(haystack string, needle string) bool {
	return strings.HasPrefix(haystack, needle)
}
func StrIsEndWith(haystack string, needle string) bool {
	return strings.HasSuffix(haystack, needle)
}

func After(haystack string, needle string) string {
	temp := haystack
	arr := strings.SplitN(haystack, needle, 2)
	if len(arr) >= 2 {
		temp = arr[1]
	}
	return temp
}
func AfterLast(haystack string, needle string) string {

	arr := strings.Split(haystack, needle)

	return arr[len(arr)-1]
}
func Before(haystack string, needle string) string {

	arr := strings.Split(haystack, needle)
	arrLen := len(arr)
	fmt.Println(arrLen)
	if arrLen >= 2 {
		arr = arr[0 : arrLen-1]
	}
	temp := ""
	for i, v := range arr {
		if i > 0 {
			v = needle + v
		}
		temp += v
	}

	return temp
}

func BeforeFirst(haystack string, needle string) string {

	arr := strings.SplitN(haystack, needle, 2)

	return arr[0]
}

func SnakeString(s string) string {
	data := make([]byte, 0, len(s)*2)
	j := false
	num := len(s)
	for i := 0; i < num; i++ {
		d := s[i]
		if i > 0 && d >= 'A' && d <= 'Z' && j {
			data = append(data, '_')
		}
		if d != '_' {
			j = true
		}
		data = append(data, d)
	}
	return strings.ToLower(string(data))
}

func CamelString(s string) string {
	data := make([]byte, 0, len(s))
	flag, num := true, len(s)-1
	for i := 0; i <= num; i++ {
		d := s[i]
		if d == '_' {
			flag = true
			continue
		} else if flag {
			if d >= 'a' && d <= 'z' {
				d = d - 32
			}
			flag = false
		}
		data = append(data, d)
	}
	return string(data)
}

func IsDigit(s string) bool {
	_, err := strconv.ParseFloat(s, 64)

	return nil == err
}
